Skip to content

fix: the User-Agent names the program running the CLI, given in REPLY_CLIENT - #33

Merged
ArtemKosolap merged 1 commit into
mainfrom
dev/REPLY-53556-client-marker
Oct 29, 2026
Merged

ArtemKosolap merged 1 commit into
mainfrom
dev/REPLY-53556-client-marker

Conversation

@ArtemKosolap

Copy link
Copy Markdown
Contributor

fix: the User-Agent names the program running the CLI, given in REPLY_CLIENT

What changed

  • A new environment variable, REPLY_CLIENT, read through the same get_env as the other REPLY_ variables. When it holds one product token and its version, user_agent() puts it before the CLI's own token: with REPLY_CLIENT=jason-harness/0.22.0 every request carries User-Agent: jason-harness/0.22.0 reply-cli/0.17.2. The CLI's token stays last.
  • Well-formed means ^[a-z][a-z0-9-]{0,31}/[0-9A-Za-z.+-]{1,32}$: a lower-case name of up to 32 letters, digits or dashes that starts with a letter, a /, and a version of up to 32 letters, digits, dots, + or -. No space, no second slash, nothing after the version.
  • Any other value, an empty one included, is left out and the User-Agent stays reply-cli/<version>, exactly as before. The variable is a label, not an input: it never refuses a command and never prints a notice.
  • The release check sends the same user_agent(), so it carries the same prefix.
  • The README lists REPLY_CLIENT in the environment variables table, next to REPLY_NO_UPDATE_CHECK, with a paragraph on what it is for, its form, and that the Jason harness sets it.
  • There is no new header, configuration key or flag. The variable is set per process by whoever starts the CLI and leaves nothing on the machine.

Why

The CLI already names itself on every request, and Reply logs that header. A program that runs the CLI on a person's behalf, such as an agent harness, had no way to say so, so Reply could not tell those calls apart from the person's own API work, per user and per version. A product token in front of the CLI's own is the usual way a User-Agent names the layer above it, and it needs no change on Reply's side to be read.

The check is strict because the value lands in a request header: a space, a line break or a second token would change what the header says. A value that fails the check is dropped silently rather than refused, so a typo in a wrapper never stops a command from running.

How it was verified

  • npm run build && npm test: before, 928 passed and 5 skipped; after, 932 passed and 5 skipped.
  • The tests were written first and seen failing: three failed before user_agent() read the variable.
  • src/__tests__/config.test.ts:
    • unset, the User-Agent is reply-cli/<version>, unchanged;
    • jason-harness/0.22.0, a/1, x9/1.0.0-rc.1+build.7, a 32-character name with a 32-character version, and my-tool/V2 are each put before reply-cli/<version>;
    • each of these is left out, the User-Agent unchanged: empty, a space, a space in the name or the version, no version, an empty version, an empty name, a 33-character name or version, an upper-case name, a name starting with a digit or a dash, an underscore, a second slash, a comment after the version, a space at either end, a trailing line break, a line break followed by another header, a trailing ;, and a non-ASCII letter in the name or the version;
    • with no argument, user_agent() reads the process environment.
  • src/__tests__/utils/client.test.ts: a request made with REPLY_CLIENT=jason-harness/0.22.0 carries jason-harness/0.22.0 reply-cli/<version>, and one made with a malformed value carries reply-cli/<version>.
  • These mutations were run against the change, and a test failed for each one: an upper-case first letter allowed, a 33-character name, a 33-character version, an empty version, a space in the version, either anchor dropped, the multiline flag, the check removed, the client put after the CLI's token, the variable never read, and the process environment not read by default.
  • Every test runs offline with fetch stubbed. No call reaches Reply.

…_CLIENT

The CLI names itself on every request as reply-cli/<version>, but a program that runs it for a
person, such as an agent harness, could not say so, and Reply could not tell those calls apart
from the person's own. REPLY_CLIENT, set to one product token and its version, now goes before the
CLI's own token: REPLY_CLIENT=jason-harness/0.22.0 sends jason-harness/0.22.0 reply-cli/0.17.2.
The release check sends the same User-Agent. A value that is not a lower-case name of up to 32
characters, a slash and a version of up to 32 is left out and the User-Agent stays as it was: the
variable is a label, so it never refuses a command and never prints anything. The README lists it
beside the other environment variables.
@ArtemKosolap
ArtemKosolap disabled auto-merge October 29, 2026 16:39
@ArtemKosolap
ArtemKosolap merged commit c770a71 into main Oct 29, 2026
6 checks passed
@ArtemKosolap
ArtemKosolap deleted the dev/REPLY-53556-client-marker branch October 29, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant